package main

import (
	"fmt"
	"reflect"
	"unsafe"
)

func main() {
	valueOf := reflect.ValueOf(sum)
	pointer := getPointer(valueOf)
	funcAddr := *(*uintptr)(pointer)
	fmt.Printf("%T\n", funcAddr)
	fmt.Printf("%v\n", funcAddr)
	f := sum
	funcAddr = **(**uintptr)(unsafe.Pointer(&f))
	fmt.Printf("%T\n", funcAddr)
	fmt.Printf("%v\n", funcAddr)
	funcAddr = valueOf.Pointer()
	fmt.Printf("%T\n", funcAddr)
	fmt.Printf("%v\n", funcAddr)
}

func getPointer(v reflect.Value) unsafe.Pointer {
	// &v -> Pointer(*int) -> *funcValue -> Pointer
	return (*funcValue)(unsafe.Pointer(&v)).p
}

type funcValue struct {
	_ uintptr
	p unsafe.Pointer
}

func sum(nums ...int) int {
	res := 0
	for _, num := range nums {
		res += num
	}
	return res
}
